# -*- coding: utf-8 -*-
# Author   : ZhangQing
# Time     : 2025-08-06 7:18
# File     : logging_middleware.py
# Project  : codebuddy_craft
# Desc     :

# backend/middleware/logging_middleware.py (修正版本)
"""
日志中间件 📝

记录HTTP请求和响应的中间件
"""

import time
import json
from typing import Callable
from starlette.middleware.base import BaseHTTPMiddleware  # ✅ 正确的导入
from starlette.requests import Request
from starlette.responses import Response
from starlette.types import ASGIApp

from backend.utils.logger import get_logger
from backend.utils.log_utils import log_api_request, log_api_response


class LoggingMiddleware(BaseHTTPMiddleware):
    """HTTP请求日志中间件 🌐"""

    def __init__(self, app: ASGIApp, logger_name: str = "http"):
        super().__init__(app)
        self.logger = get_logger(logger_name)

    async def dispatch(self, request: Request, call_next: Callable) -> Response:
        """处理HTTP请求并记录日志"""
        start_time = time.time()

        # 获取请求信息
        request_info = {
            "method": request.method,
            "path": request.url.path,
            "query_params": dict(request.query_params),
            "client_host": request.client.host if request.client else "unknown",
            "user_agent": request.headers.get("user-agent", "unknown"),
            "content_type": request.headers.get("content-type"),
            "content_length": request.headers.get("content-length"),
            "remote_addr": request.headers.get("x-forwarded-for") or
                           (request.client.host if request.client else "unknown")
        }

        # 记录请求
        log_api_request(request_info)

        try:
            # 处理请求
            response = await call_next(request)

            # 计算处理时间
            process_time = time.time() - start_time

            # 记录响应
            response_info = {
                "method": request.method,
                "path": request.url.path,
                "status_code": response.status_code,
                "duration": process_time,
                "response_size": response.headers.get("content-length")
            }

            log_api_response(response_info)

            # 添加处理时间到响应头
            response.headers["X-Process-Time"] = str(process_time)

            return response

        except Exception as e:
            # 记录异常
            process_time = time.time() - start_time

            self.logger.error(
                f"❌ 请求处理异常: {request.method} {request.url.path} "
                f"({process_time:.3f}s) - {type(e).__name__}: {e}",
                exc_info=True,
                extra={
                    "event_type": "request_exception",
                    "method": request.method,
                    "path": request.url.path,
                    "duration": process_time,
                    "exception_type": type(e).__name__,
                    "exception_message": str(e),
                    "client_host": request.client.host if request.client else "unknown"
                }
            )
            raise
